﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Linq;

namespace Bing
{
    /// <summary>
    /// Contains an array of results returned for a request to the MobileWeb <see cref="ApiHelper.SourceType"/>, as well as properties indicating total number and positioning of results.
    /// </summary>
    [DebuggerDisplay("Total={Total}, Results={Results.Count}, Errors={Errors.Count}")]
    public class MobileWebResponse: SearchResponseBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="MobileWebResponse"/> class.
        /// </summary>
        public MobileWebResponse(XContainer element)
            : base(element)
        {
            Results = new List<MobileWebResult>();
        }

        /// <summary>
        /// Gets or sets a number that represents an <b><i>estimate</i></b> of the total number of results returned by the <see cref="MobileWebRequest"/>.
        /// </summary>
        /// <value>Returns a number that represents an <b><i>estimate</i></b> of the total number of results returned by the <see cref="MobileWebRequest"/>.</value>
        /// <remarks>
        /// Based on a number of technical reasons, which are beyond the scope of this documentation, the Bing Engine does not return an exact total for a <see cref="MobileWebRequest"/>.<br />
        /// Bing is designed to handle this approximation when paging through results. If the number of results remaining, in the actual total set of results from the specified offset, is equal to or greater than the number of results requested in the MobileWebRequest.Count field, the requested number of results is returned.<br />
        /// If the number of results remaining is less than the number requested, the Bing Engine returns the remaining results without error.<br />
        /// </remarks>
        public UInt32 Total { get; set; }

        /// <summary>
        /// Gets or sets the actual offset, from zero, for the starting point of the result set that is returned from the corresponding MobileWebRequest.
        /// </summary>
        /// <value>Returns the actual offset, from zero, for the starting point of the result set that is returned from the corresponding MobileWebRequest.</value>
        /// <remarks>Typically, Offset is used in conjunction with the Count field on the MobileWebRequest object, and the Total field on the MobileWebResponse object, to facilitate paging through long lists of results.</remarks>
        public UInt32 Offset { get; set; }


        /// <summary>
        /// Gets or sets the List of results returned for this <see cref="MobileWebRequest"/>.
        /// </summary>
        /// <value>List of <see cref="MobileWebResult"/>s returned for this <see cref="MobileWebRequest"/>.</value>
        public List<MobileWebResult> Results { get; set;}

        /// <summary>
        /// Parses the response from the Bing API.
        /// </summary>
        /// <param name="element">The XML from the Bing API</param>
        /// <returns>An <see cref="MobileWebResponse" /></returns>
        public static MobileWebResponse ParseElement(XContainer element)
        {
            MobileWebResponse mobileWebResponse = new MobileWebResponse(element);
            if (mobileWebResponse.Errors.Count > 0) return mobileWebResponse;

            var mobileWeb = element.Element(XName.Get("MobileWeb", ApiHelper.MobileWebNs));
            if (mobileWeb == null) return mobileWebResponse;

            mobileWebResponse.Total = ApiHelper.GetElementValueOrDefault<UInt32>(mobileWeb, "Total", ApiHelper.MobileWebNs);
            mobileWebResponse.Offset = ApiHelper.GetElementValueOrDefault<UInt32>(mobileWeb, "Offset", ApiHelper.MobileWebNs);

            XElement mobileWebResults = mobileWeb.Element(XName.Get("Results", ApiHelper.MobileWebNs));

            if (mobileWebResults == null) return mobileWebResponse;
            foreach (XElement result in mobileWebResults.Elements(XName.Get("MobileWebResult", ApiHelper.MobileWebNs)))
            {
                MobileWebResult mobileWebResult = new MobileWebResult();
                mobileWebResult.Title = ApiHelper.GetElementValueOrDefault<string>(result, "Title", ApiHelper.MobileWebNs);
                mobileWebResult.Url = ApiHelper.GetElementValueOrDefault<string>(result, "Url", ApiHelper.MobileWebNs);
                mobileWebResult.DisplayUrl = ApiHelper.GetElementValueOrDefault<string>(result, "DisplayUrl", ApiHelper.MobileWebNs);
                mobileWebResult.Description = ApiHelper.GetElementValueOrDefault<string>(result, "Description", ApiHelper.MobileWebNs);
                mobileWebResult.DateTime = ApiHelper.GetElementValueOrDefault<DateTime>(result, "DateTime", ApiHelper.MobileWebNs);

                mobileWebResponse.Results.Add(mobileWebResult);
            }

            return mobileWebResponse;
        }
    }
}
